﻿using googleMap.Web.Dao;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ZedGraph;

namespace googleMap.Web.Controllers
{
    public class ChartImgController : Controller
    {
        public ActionResult Browse(string a,string id)
        {
            GraphPane myPane = null;
            if (!string.IsNullOrEmpty(Request["id"]) && !string.IsNullOrEmpty(Request["a"]))
            {
                switch (Request["a"])
                {
                    case "waterchart":
                        myPane = this.WaterChart(Request["id"]);

                        
                        break;
                }
            }

            if (myPane != null)
            {
                #region 繪製Chart
                int width = 440;
                int height = 400;

                if (!string.IsNullOrEmpty(Request["w"]))
                {
                    int oWidth = 0;
                    if (int.TryParse(Request["w"].ToString(), out oWidth))
                    {
                        width = oWidth;
                    }
                }

                if (!string.IsNullOrEmpty(Request["h"]))
                {
                    int oHeight = 0;
                    if (int.TryParse(Request["h"].ToString(), out oHeight))
                    {
                        height = oHeight;
                    }
                }


                Bitmap image = myPane.GetImage(width, height, 1024);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                byte[] bytes = ms.ToArray();
                #endregion
                return File(bytes, @"image/jpeg");
            }

            return View();
        }

        #region 私有方法
        private string GetLevel(object val)
        {
            if (val != DBNull.Value)
            {
                if (!string.IsNullOrEmpty(val.ToString()))
                {
                    string sResult = val.ToString();
                    double dResult = 0.0;
                    if (double.TryParse(sResult, out dResult))
                    {
                        return dResult.ToString();
                    }
                }
            }
            return "0.0";
        }

        protected List<WaterChartModel> WaterChartSource(string StationNo)
        {
            using (var mapsDao = new pwbGoogleMapsEntities())
            {
                DateTime dtmNow = System.DateTime.Now;
                var ctlDao = mapsDao.app_water_level_hour.AsQueryable();
                string strWhere = "stationno = '" + StationNo + "' and RecTime >= '" + dtmNow.AddHours(-24).ToString("yyyyMMddHHmm") + "' and RecTime <= '" + dtmNow.ToString("yyyyMMddHHmm") + "'"; ;
                string strSQL = "select * from app_water_level_hour where " + strWhere;

                var list = mapsDao.Database.SqlQuery<app_water_level_hour>(strSQL).ToList();

                DataSet WaterDS = DataSetHelper.ConvertToDataSet<app_water_level_hour>(list);

                #region 水位站24小時
                List<WaterChartModel> WaterList = new List<WaterChartModel>();

                for (int j = 23; j >= 0; j--)
                {
                    string rectime = dtmNow.AddHours(j * -1).ToString("yyyyMMddHH00");
                    string where = "RecTime='" + rectime + "'";
                    var args = WaterDS.Tables[0].Select(where);

                    WaterChartModel WaterModel = new WaterChartModel();
                    int index = 0;
                    if (args.Length > 0)
                    {
                        WaterModel.RecTime = rectime;
                        WaterModel.LevelOut = double.Parse(GetLevel(args[0]["LevelOut"]));
                    }
                    else
                    {
                        double dLevelOut = 0;
                        if (index - 1 >= 0)
                        {
                            dLevelOut = WaterList[index - 1].LevelOut;
                        }
                        else
                        {
                            dLevelOut = 0;
                        }

                        WaterModel.RecTime = rectime;
                        WaterModel.LevelOut = dLevelOut;
                    }

                    WaterList.Add(WaterModel);
                }
                #endregion


                return WaterList;
            }
        }

        protected List<WaterVoltageChartModel> WaterVoltageChartSource(string StationNo)
        {
            using (var mapsDao = new pwbGoogleMapsEntities())
            {
                DateTime dtmNow = System.DateTime.Now;

                string strWhere = "stationno = '" + StationNo + "' and RecTime >= '" + dtmNow.AddHours(-24).ToString("yyyyMMddHHmm") + "' and RecTime <= '" + dtmNow.ToString("yyyyMMddHHmm") + "'"; ;
                string strSQL = "select * from app_water_level_voltage_hour where " + strWhere;

                var list = mapsDao.Database.SqlQuery<app_water_level_voltage_hour>(strSQL).ToList();
                DataSet WaterVoltageDS = DataSetHelper.ConvertToDataSet<app_water_level_voltage_hour>(list);

                #region 水位站電壓24小時
                List<WaterVoltageChartModel> WaterVoltageList = new List<WaterVoltageChartModel>();
                for (int j = 23; j >= 0; j--)
                {
                    string rectime = dtmNow.AddHours(j * -1).ToString("yyyyMMddHH00");
                    string where = "RecTime='" + rectime + "'";
                    var args = WaterVoltageDS.Tables[0].Select(where);

                    WaterVoltageChartModel WaterVoltageModel = new WaterVoltageChartModel();
                    int index = 0;
                    if (args.Length > 0)
                    {
                        WaterVoltageModel.RecTime = rectime;
                        WaterVoltageModel.Voltage = double.Parse(GetLevel(args[0]["Voltage"]));
                    }
                    else
                    {
                        double dVoltage = 0;
                        if (index - 1 >= 0)
                        {
                            dVoltage = WaterVoltageList[index - 1].Voltage;
                        }
                        else
                        {
                            dVoltage = 0;
                        }

                        WaterVoltageModel.RecTime = rectime;
                        WaterVoltageModel.Voltage = dVoltage;
                    }

                    WaterVoltageList.Add(WaterVoltageModel);
                }
                #endregion

                return WaterVoltageList;
            }
        }

        private GraphPane WaterChart(string id)
        {
            GraphPane myPane = new GraphPane();
            #region easy code
            using (var mapsDao = new pwbGoogleMapsEntities())
            {
                var station = mapsDao.gm2012_ctl_was_station.Where(m => m.StationNO == id).ToList().FirstOrDefault();

                double min = 0;
                double max = 0;
                double step = 0;

                //如果該水位站有電壓需要顯示電壓
                if (station == null)
                    return null;
                if (station.HaveVoltage == 1)
                {
                    myPane = this.WaterVoltageChart(id);
                }
                else
                {
                    var WaterDataSource = this.WaterChartSource(id);

                    PointPairList WaterLevelOut = new PointPairList();
                    foreach (var item in WaterDataSource)
                    {
                        DateTime recTime = RainEx.StringToDTM(item.RecTime);
                        double x = new XDate(recTime);
                        WaterLevelOut.Add(x, item.LevelOut);
                    }

                    myPane = new GraphPane();
                    var font = new FontSpec();
                    font.Size = 14;
                    font.Border = new Border(false, Color.White, 0);



                    LineItem myCurve1H = myPane.AddCurve("水位高度", WaterLevelOut, Color.Blue, SymbolType.Diamond);
                    myCurve1H.Symbol.Fill = new Fill(Color.Blue);
                    myCurve1H.Symbol.Size = 5;
                    myCurve1H.Label.FontSpec = font;

                    myPane.XAxis.Type = AxisType.Date;
                    myPane.XAxis.Scale.FontSpec.Size = 16;
                    myPane.XAxis.Scale.FontSpec.Family = "verdana";
                    myPane.XAxis.Scale.Format = "MM/dd\r\nHH:00";
                    myPane.XAxis.Scale.FontSpec.IsAntiAlias = true;

                    myPane.YAxis.Scale.FontSpec.FontColor = Color.Blue;
                    myPane.YAxis.Title.FontSpec.FontColor = Color.Blue;


                    myPane.XAxis.Scale.MajorUnit = DateUnit.Hour;
                    myPane.XAxis.Scale.Min = new XDate(Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd HH:00")).AddHours(-23));
                    myPane.XAxis.Scale.Max = new XDate(Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd HH:00")));
                    myPane.XAxis.MajorGrid.IsVisible = true;
                    myPane.YAxis.MajorGrid.IsVisible = true;
                    myPane.XAxis.MajorGrid.Color = Color.LightGray;
                    myPane.YAxis.MajorGrid.Color = Color.LightGray;
                    myPane.YAxis.MajorGrid.DashOff = 0;
                    myPane.XAxis.MajorGrid.DashOff = 0;
                    myPane.YAxis.MajorGrid.IsZeroLine = true;
                    myPane.YAxis.Scale.Align = AlignP.Inside;


                    //步長
                    min = WaterDataSource.Min(m => m.LevelOut);
                    max = WaterDataSource.Max(m => m.LevelOut);
                    //步長
                    if (max - min <= 1)
                    {
                        step = 0.5;

                        max += step;
                        min -= step;
                    }
                    else if (max - min <= 10)
                    {
                        step = 1;
                    }
                    else if (max - min <= 100)
                    {
                        step = 10;
                    }
                    else if (max - min <= 200)
                    {
                        step = 20;
                    }
                    else if (max - min <= 300)
                    {
                        step = 30;
                    }
                    else if (max - min <= 500)
                    {
                        step = 50;
                    }
                    else
                    {
                        step = 100;
                    }
                    myPane.YAxis.Scale.MajorStep = step;

                    max = Math.Floor(max) + 1;
                    min = Math.Floor(min) - 1;

                    myPane.YAxis.Scale.Min = min;
                    myPane.YAxis.Scale.Max = max;

                    myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f);
                    myPane.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 225), 45);
                    myPane.AxisChange();

                    this.DisplayChart(myPane);
                }
            }

            #endregion

            return myPane;
        }

        private GraphPane WaterVoltageChart(string id)
        {
            #region easy code
            var WaterDataSource = this.WaterChartSource(id);

            var WaterVoltageDataSource = this.WaterVoltageChartSource(id);
            double min = 0;
            double max = 0;
            double step = 0;
            PointPairList WaterLevelOut = new PointPairList();
            foreach (var item in WaterDataSource)
            {
                DateTime recTime = RainEx.StringToDTM(item.RecTime);
                double x = new XDate(recTime);
                WaterLevelOut.Add(x, item.LevelOut);
            }

            PointPairList WaterVoltage = new PointPairList();
            foreach (var item in WaterVoltageDataSource)
            {
                DateTime recTime = RainEx.StringToDTM(item.RecTime);
                double x = new XDate(recTime);
                WaterVoltage.Add(x, item.Voltage);
            }


            GraphPane myPane = new GraphPane();
            var font = new FontSpec();
            font.Size = 14;
            font.Border = new Border(false, Color.White, 0);


            //水位
            LineItem myCurve = myPane.AddCurve("水位高度", WaterLevelOut, Color.Blue, SymbolType.Diamond);
            myCurve.Symbol.Fill = new Fill(Color.Blue);
            myCurve.Symbol.Size = 5;
            myCurve.Label.FontSpec = font;

            //電壓
            myCurve = myPane.AddCurve("電壓", WaterVoltage, Color.Red, SymbolType.Diamond);
            myCurve.Symbol.Fill = new Fill(Color.Red);
            myCurve.Symbol.Size = 5;
            myCurve.Label.FontSpec = font;
            myCurve.IsY2Axis = true;

            myPane.XAxis.Type = AxisType.Date;
            myPane.XAxis.Scale.FontSpec.Size = 16;
            myPane.XAxis.Scale.FontSpec.Family = "verdana";
            myPane.XAxis.Scale.Format = "MM/dd\r\nHH:00";
            myPane.XAxis.Scale.FontSpec.IsAntiAlias = true;

            myPane.YAxis.Scale.FontSpec.FontColor = Color.Blue;
            myPane.YAxis.Title.FontSpec.FontColor = Color.Blue;

            myPane.XAxis.Scale.MajorStep = 1;
            myPane.XAxis.Scale.MajorUnit = DateUnit.Hour;
            myPane.XAxis.Scale.Min = new XDate(Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd HH:00")).AddHours(-23));
            myPane.XAxis.Scale.Max = new XDate(Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd HH:00")));
            myPane.XAxis.MajorGrid.IsVisible = true;

            myPane.XAxis.MajorGrid.Color = Color.LightGray;

            myPane.XAxis.MajorGrid.DashOff = 0;

            //myPane.YAxis.Scale.MajorStep = 0.5;
            myPane.YAxis.MajorGrid.IsVisible = true;
            myPane.YAxis.MajorGrid.Color = Color.LightGray;
            myPane.YAxis.MajorGrid.DashOff = 0;
            myPane.YAxis.MajorGrid.IsZeroLine = true;
            myPane.YAxis.Scale.Align = AlignP.Inside;
            min = WaterDataSource.Min(m => m.LevelOut);
            max = WaterDataSource.Max(m => m.LevelOut);
            //步長
            if (max - min <= 1)
            {
                step = 0.5;

                max += step;
                min -= step;
            }
            else if (max - min <= 10)
            {
                step = 1;
            }
            else if (max - min <= 100)
            {
                step = 10;
            }
            else if (max - min <= 200)
            {
                step = 20;
            }
            else if (max - min <= 300)
            {
                step = 30;
            }
            else if (max - min <= 500)
            {
                step = 50;
            }
            else
            {
                step = 100;
            }
            myPane.YAxis.Scale.MajorStep = step;

            max = Math.Floor(max) + 1;
            min = Math.Floor(min) - 1;

            myPane.YAxis.Scale.Min = min;
            myPane.YAxis.Scale.Max = max;




            myPane.Y2Axis.MajorGrid.IsVisible = true;
            myPane.Y2Axis.IsVisible = true;
            myPane.Y2Axis.Scale.FontSpec.FontColor = Color.Red;
            myPane.Y2Axis.Title.FontSpec.FontColor = Color.Red;
            myPane.Y2Axis.MajorGrid.IsZeroLine = true;
            myPane.Y2Axis.Scale.Align = AlignP.Inside;

            min = WaterVoltageDataSource.Min(m => m.Voltage);
            max = WaterVoltageDataSource.Max(m => m.Voltage);
            if (min >= 9)
            {
                min = 9;
            }
            if (max <= 15)
            {
                max = 15;
            }
            //if (min != max)
            //{
            //    myPane.Y2Axis.Scale.Min = 8;
            //    myPane.Y2Axis.Scale.Max = max;
            //}
            myPane.Y2Axis.Scale.MajorStep = 1;
            myPane.Y2Axis.Scale.Min = min;
            myPane.Y2Axis.Scale.Max = max;

            myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0f);
            myPane.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 225), 45);
            myPane.AxisChange();

            #endregion

            return myPane;

            //this.DisplayChart(myPane);

        }

        /// <summary>
        /// 顯示Chart圖并輸出至頁面中
        /// </summary>
        /// <param name="myPane"></param>
        private void DisplayChart(GraphPane myPane)
        {
            int width = 440;
            int height = 400;

            if (!string.IsNullOrEmpty(Request["w"]))
            {
                int oWidth = 0;
                if (int.TryParse(Request["w"].ToString(), out oWidth))
                {
                    width = oWidth;
                }
            }

            if (!string.IsNullOrEmpty(Request["h"]))
            {
                int oHeight = 0;
                if (int.TryParse(Request["h"].ToString(), out oHeight))
                {
                    height = oHeight;
                }
            }


            Bitmap image = myPane.GetImage(width, height, 1024);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            Response.ClearContent();
            Response.ContentType = "image/Png";
            Response.BinaryWrite(ms.ToArray());
            image.Dispose();
        }

        #endregion
    }
}